﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoodStuff
{
    public struct DateRange : IDateRange
    {
        public DateTime Start { get; private set; }
        public DateTime End { get; private set; }

        public DateRange(DateTime start, DateTime end):this()
        {
            if (end <= start)
            {
                throw new ArgumentException("Duration must be a positive value");
            }

            Start = start;
            End = end;
        }

        public DateRange(DateTime now, TimeSpan timeSpan):this()
        {
            if (timeSpan.Ticks <= 0)
            {
                throw new ArgumentException("Duration must be a positive value");
            }
            // TODO: Complete member initialization
            Start = now;
            End = now + timeSpan;
        }

        public TimeSpan Duration
        {
            get { return End - Start; }
        }   
     
        public static bool operator > (DateTime time, DateRange range)
        {
            return time > range.End;
        }

        public static bool operator >=(DateTime time, DateRange range)
        {
            return time >= range.End;
        }

        public static bool operator <(DateTime time, DateRange range)
        {
            return time < range.Start;
        }

        public static bool operator <=(DateTime time, DateRange range)
        {
            return time <= range.Start;
        }
    }

    public interface IDateRange
    {
        DateTime Start { get; }
        DateTime End { get; }
        TimeSpan Duration { get; }
    }

    public static class IDateRangeExtensions
    {
        public static bool Overlaps(this IDateRange range1, IDateRange range2)
        {
            //er is GEEN overlap als de range2 voor de start eindigd, of na het einde begint.
            if (range2.End < range1.Start)
            {
                return false;
            }

            if (range2.Start > range1.End)
            {
                return false;
            }

            return true;
        }

        public static bool IsInRange(this IDateRange range1, DateTime datetime)
        {
            if (range1.Start <= datetime && datetime <= range1.End)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Clips the daterange so it never exceeds the second range
        /// </summary>
        /// <param name="range1"></param>
        /// <param name="range2"></param>
        /// <returns></returns>
        public static IDateRange Clip(this IDateRange range1, IDateRange range2)
        {
            if (!range1.Overlaps(range2))
            {
                return null;
            }

            DateTime minStart = range1.Start < range2.Start ? range2.Start : range1.Start;
            DateTime maxEnd = range1.End > range2.End ? range2.End : range1.End;

            return new DateRange(minStart, maxEnd);
        }
    }


}
